package com.multitrack.main;

import static com.multitrack.datatype.SocketMessage.EVENT_JOIN;
import static com.multitrack.datatype.SocketMessage.getEnum;

import java.util.List;

import android.app.Activity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

import com.multitrack.datatype.Event;
import com.multitrack.datatype.EventData;
import com.multitrack.datatype.Identity;
import com.multitrack.datatype.IdentityList;
import com.multitrack.datatype.STATE;
import com.multitrack.datatype.SocketMessage;
import com.multitrack.datatype.TYPE;
import com.multitrack.map.EventMapActivity;
import com.multitrack.nfc.NdefMessageParser;
import com.multitrack.nfc.ParsedRecord;
import com.multitrack.nfc.TextRecord;
import com.multitrack.util.CloseAlertDialog;
import com.multitrack.util.CommunicationManager;
import com.multitrack.util.EventListAdapter;
import com.multitrack.util.EventSQLite;
import com.multitrack.util.Progress;
import com.multitrack.util.ThreadManager;

public class EventTagActivity extends Activity {

	private final String TAG = "EventTagActivity";
	private String[] mTags;

	private ListView eventTagView;
	private Identity event;
	private IdentityList events;
	private EventListAdapter adapter;

	private Event currEvent;

	private CommunicationManager joinEvent;

	private Progress mProgress;
	
	private EventSQLite mHelper;
	
	Intent nfcIntent;
	String[] nfcTags;
	Event nfcEvent;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.event_tag_activity);
		
		currEvent = new Event();
		
		events = new IdentityList();
		mProgress = new Progress(this);
		mHelper = new EventSQLite(this);

		Intent intent = getIntent();
		
		if (intent != null) {
			readNFCMessage(intent);
		}
		

		eventTagView = (ListView) findViewById(R.id.event_tag_list);
		adapter = new EventListAdapter(this, R.layout.event_item_activity,
				events);
		eventTagView.setAdapter(adapter);
		eventTagView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
		eventTagView.setOnItemClickListener(eventItemClickListener);

		adapter.notifyDataSetChanged();
	}

	private void readNFCMessage(Intent passedIntent) {
		// NFC 메시지 받는 부분

		if (passedIntent == null) {
			return;
		}

		String action = passedIntent.getAction();

		if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action) == false) {
			return;
		}

		// 입려된 태그 파싱 및 입력
		if (processTag(passedIntent) == false) {
			readErrorTag();
			return;
		}

	}

	private boolean processTag(Intent passedIntent) {
		Parcelable[] rawMsgs = passedIntent
				.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
		if (rawMsgs == null) {
			Log.d(TAG, "NDEF is null.");
			// 알 수 없는 메시지
			return false;
		}

		// 읽은 태그가 2개가 아닌 경우
//		if (rawMsgs.length != 2) {
//			return false;
//		}

		NdefMessage[] msgs;
		if (rawMsgs != null) {
			msgs = new NdefMessage[rawMsgs.length];

			for (int i = 0; i < rawMsgs.length; i++) {
				msgs[i] = (NdefMessage) rawMsgs[i];
				readTag(msgs[i]);
			}
		}

		if (checkEventMessage(nfcTags) == false) {
			readErrorTag();
			return false;
		}

		// ex) 2012-09-13 18:58:43, event name
		
		events.add(new Identity(nfcTags[0], nfcTags[1]));
		
		return true;
	}

	private boolean checkEventMessage(String[] msg) {

		// TODO: dummy

		return true;
	}

	private int readTag(NdefMessage mMessage) {
		List<ParsedRecord> records = NdefMessageParser.parse(mMessage);
		final int size = records.size();
		nfcTags = new String[size];
		for (int i = 0; i < size; i++) {
			ParsedRecord record = records.get(i);

			int recordType = record.getType();
			nfcTags[i] = new String();
			if (recordType == ParsedRecord.TYPE_TEXT) {
				nfcTags[i] = ((TextRecord) record).getText();
			} else if (recordType == ParsedRecord.TYPE_URI) {
				return -1;
			} else {
				// 알 수 없는 메시지
				return -1;
			}
			Log.d(TAG, nfcTags[i]);
		}

		return size;
	}

	private void readErrorTag() {
		OnClickListener listener = new OnClickListener() {

			public void onClick(DialogInterface dialog, int which) {
				finish();
			}
		};

		new CloseAlertDialog(EventTagActivity.this, R.string.notice,
				R.string.cannot_read_tag, listener).show();
	}

	// View 선택 리스너
	AdapterView.OnItemClickListener eventItemClickListener = new AdapterView.OnItemClickListener() {
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			currEvent.setId(events.get(position).getId());
			currEvent.setName(events.get(position).getName());

			OnClickListener listener = new OnClickListener() {

				public void onClick(DialogInterface dialog, int which) {
					excuteJoin(currEvent);
				}
			};

			new CloseAlertDialog(EventTagActivity.this, R.string.notice,
					R.string.question_connect, listener, null).show();

		}
	};


	/**
	 * SubThread -> Messages -> MainThread(UI)
	 */
	Handler mHandler = new Handler() {

		SocketMessage message;
		STATE resultState;
		Object resultValue;

		@Override
		public void handleMessage(Message msg) {

			message = getEnum(msg.arg1);
			resultState = STATE.getEnum(msg.what);
			resultValue = msg.obj;

			switch (message) {

			case EVENT_JOIN:
				eventJoin();
				break;

			default:
				unknownMessage(message);
				break;
			}
		}

		private void eventJoin() {
			if (mProgress.isShowing()) {
				mProgress.dismiss();
			}

			switch (resultState) {
			case SOCKET_SUCCESS:
				eventJoinUponSuccess();
				break;
			case SOCKET_FAIL:
				eventJoinUponFail();
				break;
			case SOCKET_EXCEPTION:
				eventJoinUponException();
				break;
			default:
				unknownMessage(resultState);
				break;
			}
		}

		private void eventJoinUponSuccess() {

			switch ((SocketMessage) resultValue) {

			case BLACK_LIST:
				new CloseAlertDialog(EventTagActivity.this, R.string.notice,
						R.string.deny_join_event, null).show();
				break;

			case ALREADY_JOIN_MEMBER_IN_EVENT:
			case SQL_QUERY_SUCCESS:
				Intent intent = new Intent(EventTagActivity.this,
						EventMapActivity.class);
				intent.putExtra(TYPE.EVENT, currEvent);
				startActivity(intent);
				finish();
				break;

			case SQL_QUERY_FAIL:
				break;

			case SQL_QUERY_ERROR:

				break;

			default:
				unknownMessage((SocketMessage) resultValue);
				break;
			}
		}

		private void eventJoinUponFail() {
			uponFail();
		}

		private void eventJoinUponException() {
			OnClickListener listener = new OnClickListener() {

				public void onClick(DialogInterface dialog, int which) {
					excuteJoin(currEvent);
				}
			};

			UponException(listener, null);

		}

		private void uponFail() {
			OnClickListener listener = new OnClickListener() {

				public void onClick(DialogInterface dialog, int which) {
					finish();
				}
			};

			new CloseAlertDialog(EventTagActivity.this, R.string.notice,
					R.string.disconnect_server, listener).show();
		}

		private void UponException(OnClickListener pListener,
				OnClickListener nListener) {
			new CloseAlertDialog(EventTagActivity.this, R.string.notice,
					R.string.fail_connect_server + R.string.reconnect, pListener,
					nListener).show();
		}

		private void unknownMessage(STATE state) {
			new CloseAlertDialog(EventTagActivity.this, R.string.notice,
					"알 수 없는 STATE (R.string) - " + state.name(), null).show();

		}

		private void unknownMessage(SocketMessage message) {
			new CloseAlertDialog(EventTagActivity.this, R.string.notice,
					"알 수 없는 MESSAGE (R.string) - " + message.name(), null)
					.show();
		}
	};

	private void excuteJoin(Event event) {

		if (ThreadManager.isInThread(joinEvent) == false) {
			if (mProgress.isShowing() == false) {
				mProgress.show();
			}
			joinEvent = new CommunicationManager();
			ThreadManager.excute(joinEvent, mHandler, EVENT_JOIN,
					new EventData(event.getId(), mHelper.dbGetMyId()));
		}
	}

	private boolean checkEventMessage(String msg) {

		// ex) 2012-09-13 18:58:43/방제목

		String id_name[] = msg.split("/");
		if (id_name.length != 2) {
			return false;
		}

		String date_time[] = id_name[0].split(" ");

		if (date_time.length != 3) {
			return false;
		}

		String yy_mm_dd[] = date_time[0].split("-");
		if (yy_mm_dd.length != 3) {
			return false;
		}

		String h_m_s[] = date_time[1].split(":");
		if (h_m_s.length != 3) {
			return false;
		}

		for (int i = 0; i < 3; i++) {
			if (Integer.getInteger(yy_mm_dd[i]) == null) {
				return false;
			}
			if (Integer.getInteger(h_m_s[i]) == null) {
				return false;
			}
		}

		return true;
	}
	
}
